package br.ufmg.vod.wbr.algorithims.dfs;

import br.ufmg.vod.wbr.api.Graph;

public class RecursiveDFS implements Runnable, DFS{
	

	
	private DFSData data;

	public RecursiveDFS(Graph g){
		this.data = new DFSData(g);
	}
	
	@Override
	public void run() {
		dfsAllVertex();
	}

	public void dfsAllVertex() {
		for (int i = 0; i < this.data.graph.getNumVertex(); i++) {
			dfsSingleVertex(i);
		}
	}

	public void dfsSingleVertex(int i) {
		if( this.data.colors[i] == DFSData.WHITE){
			int startVertex = i;
			this.data.dist[startVertex]=0;
			this.data.predecessor[startVertex]=startVertex;
			this.data.colors[startVertex] = DFSData.GRAY;
			this.data.discoveryTime[startVertex] = ++this.data.time;
			this.dfsVisit(startVertex);
		}
	}

	private void dfsVisit(int u) {

		int[] neighbours = data.graph.getEdges(u);
		for (int i = 0; i < neighbours.length; i++) {
			int v = neighbours[i];
			if( v < this.data.graph.getNumVertex() && this.data.colors[v] == DFSData.WHITE  ){
				this.data.colors[v] = DFSData.GRAY;
				this.data.discoveryTime[v] = ++this.data.time;
				this.data.predecessor[v]=u;
				this.data.dist[v]=this.data.dist[u]+1;
				this.dfsVisit(v);
			}
		}
		this.data.colors[u] = DFSData.BLACK;
		this.data.closeTime[u] = this.data.time;
//		this.data.stack.add(u);
		this.data.visitedStack.push(u);
	}
	
	
	public DFSData getData() {
		return data;
	}

	@Override
	public void clear() {
		this.data.clearAllData();
	}


}
